﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YZQ_DotNetArx.CAD
{
    public static class LayerTools
    {
        /// <summary>
        /// 创建新图层
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <param name="layerName">图层名</param>
        /// <returns>返回新建图层的ObjectId</returns>
        public static ObjectId AddLayer(this Database db, string layerName)
        {
            //打开层表
            LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead);
            if (!lt.Has(layerName)) //如果不存在名为layerName的图层，则新建一个图层
            {
                LayerTableRecord ltr = new LayerTableRecord();   //定义一个新的层表记录
                ltr.Name = layerName; //设置图层名
                lt.UpgradeOpen(); //切换层表记录的信息添加新的图层
                lt.Add(ltr);         //
                //把层表记录添加到事务处理中
                db.TransactionManager.AddNewlyCreatedDBObject(ltr, true);
                lt.DowngradeOpen();  //为了安全,将层表的状态切换为读
            }
            return lt[layerName];    //返回新添加的层表记录的ObjectId
        }
        /// <summary>
        /// 设置图层颜色
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <param name="layerName">图层名</param>
        /// <param name="colorIndex">颜色索引</param>
        /// <returns>如果成功设置图层颜色，则返回true，否则返回false</returns>
        public static bool SetLayerColor(this Database db, string layerName, short colorIndex)
        {
            //打开层表
            LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead);
            if (!lt.Has(layerName)) return false;
            ObjectId layerId = lt[layerName];  //获取名为layerName的层表记录的Id
            //以写的方式打开名为layerName的层表记录
            LayerTableRecord ltr = (LayerTableRecord)layerId.GetObject(OpenMode.ForWrite);
            ltr.Color = Color.FromColorIndex(ColorMethod.ByAci, colorIndex); //设置颜色
            ltr.DowngradeOpen();
            return true;
        }
        /// <summary>
        /// 将指定的层设置为当前层
        /// </summary>
        /// <param name="db"></param>
        /// <param name="layerName"></param>
        /// <returns></returns>
        public static bool SetCurrentLayer(this Database db, string layerName)
        {
            LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead);
            if (!lt.Has(layerName)) return false;
            ObjectId layerId = lt[layerName];
            if (db.Clayer == layerId) return false;
            db.Clayer = layerId;
            return true;
        }
        /// <summary>
        /// 获取当前图形中所有的图层
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <returns>返回所有的层表记录</returns>
        public static List<LayerTableRecord> GetAllLayers(this Database db)
        {
            //打开层表
            LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead);
            //用于返回层表记录的列表
            List<LayerTableRecord> ltrs = new List<LayerTableRecord>();
            foreach (ObjectId id in lt)
            {
                LayerTableRecord ltr = (LayerTableRecord)id.GetObject(OpenMode.ForRead);
                ltrs.Add(ltr);
            }
            return ltrs; //返回所有的层表记录
        }
        /// <summary>
        /// 删除指定名称的图层
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <param name="layerName">图层名</param>
        /// <returns>如果删除成功，则返回true，否则返回false</returns>
        public static bool DeleteLayer(this Database db, string layerName)
        {
            LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead);
            //如果层名为0或者Defpoints,则返回（这两个图层不能删除）
            if (layerName == "0" || layerName == "Defpoints") return false;
            if (!lt.Has(layerName)) return false;
            ObjectId layerId = lt[layerName];
            if (layerId == db.Clayer) return false; //如果是当前层，则返回（不能删除当前层）
            //打开层表为layerName的层表记录
            LayerTableRecord ltr = (LayerTableRecord)layerId.GetObject(OpenMode.ForRead);
            //使用lt.GenerateUsageData()方法生成AutoCAD的使用数据，
            //然后分析这些数据来确定图层中是否含有对象，
            //以及这些对象是否依赖于外部文件。
            //如果要删除的图层包含对象或依赖外部参照，则返回（不能删除这些层）
            lt.GenerateUsageData();
            if (ltr.IsUsed) return false;
            ltr.UpgradeOpen();
            ltr.Erase(true);
            return true;
        }
        /// <summary>
        /// 获取所有图层的ObjectId
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <returns>返回所有图层的ObjectId</returns>
        public static List<ObjectId> GetAllLayerObjectIds(this Database db)
        {
            LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead);
            List<ObjectId> ids = new List<ObjectId>();
            foreach (ObjectId id in lt)
            {
                ids.Add(id);
            }
            return ids;
        }
    }
}
